package com.javasm.mingming.login.service.impl;

import com.javasm.mingming.common.RedisKeys;
import com.javasm.mingming.common.exception.JavasmException;
import com.javasm.mingming.common.exception.JavasmExceptionEnum;
import com.javasm.mingming.login.service.LoginService;
import com.javasm.mingming.webuser.entity.WebUser;
import com.javasm.mingming.webuser.entity.WebUserInfo;
import com.javasm.mingming.webuser.entity.WebUserLoginLog;
import com.javasm.mingming.webuser.service.WebUserInfoService;
import com.javasm.mingming.webuser.service.WebUserLoginLogService;
import com.javasm.mingming.webuser.service.WebUserService;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit;

@Service("loginService")
public class LoginServiceImpl implements LoginService {

    //注入一个Redis对象，这样可以在这个类中进行缓存操作，如读写，写入和删除缓存数据
    @Resource
    RedisTemplate<String,Object> redisTemplate;



    @Resource
    WebUserService webUserService;
    @Resource
    WebUserLoginLogService  webUserLoginLogService;

    @Resource
    WebUserInfoService webUserInfoService;

    @Override
    public WebUser doUnameLogin(String username, String password) {
        //这里具体思考，别人给你用户名，密码，你给他用户信息，这一步是如何实现的
        //具体思考下面的东西，根据用户名 密码，查询用户信息
        WebUser webUser = webUserService.getByUname(username);
        if(webUser == null){
           throw new JavasmException(JavasmExceptionEnum.UserNotExist);
        }
        //判断密码对不对？
        if(!password.equals(webUser.getPassword())){
            throw new JavasmException(JavasmExceptionEnum.PasswordError);
        }

//TODO:推荐使用线程池，但是还没学呢，暂时使用new Thread
        new Thread(()->{

            //从Redis中查询是否有当前用户，是否有登录纪录
            //为下边的语句设置合适的时间
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMdd");
            String date = simpleDateFormat.format(new Date());
            System.out.println("111111111111111111111111111");
            String loginLogKey = String.format(RedisKeys.Login_Log_Key,date,webUser.getUid());
            Object o = redisTemplate.opsForValue().get(loginLogKey);
            if(o == null){
                //说明今天没有登录过，就可以把下边的东西给拿上去执行了
                //登录的时候，需要一起查询webuserinfo的内容，涉及到两张表
                //纪录登录信息，这个登录表是空表，所以要纪录下来登录信息，所以跟那个查询好像不太一样

                WebUserLoginLog webUserLoginLog = new WebUserLoginLog();
                webUserLoginLog.setUid(webUser.getUid());
                webUserLoginLogService.save(webUserLoginLog);

                redisTemplate.opsForValue().set(loginLogKey,webUser.getUid(),1, TimeUnit.DAYS);
                //增加需求，每天，每个用户，只纪录一个信息
                //想实现这个功能就得用到redis了，先做的事情是从Redis中查询是否有纪录，如果有的话，不用再次查询了
            }
        }).start();
       //还没加需求，开屏广告，维护信息，登录信息，手机验证码登录，等潜在需求还没有加上去，这是暂时的版本
        //
        return webUser;
    }

    @Override
    @Transactional//通过 @Transactional 注解确保操作的原子性，即要么全部成功，要么全部失败。
    public void doRegister(WebUser webUser) {
        //添加  web_user表的信息  添加web_user_info表的信息

        //这个出现404了，注册功能的代码出现问题，需要重新修复一下

        webUserService.save(webUser);
        if(webUser != null && webUser.getUserInfo()!=null){
            webUser.getUserInfo().setUid(webUser.getUid());

            //注册的时候随机分配头像
            //这个是基础头像
            String url ="http://cd.ray-live.cn/imgs/headpic/pic_%s.jpg";
            //随机生成随机数
            //线程安全的生成随机数
            int index = ThreadLocalRandom.current().nextInt(0, 70);
            webUser.getUserInfo().setHeadPic(String.format(url,index));

            webUserInfoService.save(webUser.getUserInfo());


        }
        //因为每次登录都从数据库中查询数据是一件很危险的事情，所以得存入到Redis中
        //TODO: 由于往Redis中添加数据，不属于注册主流程，要放在子线程中,增加性能
        WebUser newWebUser = webUser.clone();

        new Thread(()->{
            Integer uid = newWebUser.getUid();


            //因为数据库设置了默认值，但是这个类中是缓存，还没有默认值，所以要重新查一遍
            //配置的是数据库添加的默认值，此时的webUser.getUserInfo()是没有其他默认值属性的
            //想获取全部的数据，存入Redis，需要重新查询
            WebUserInfo  userInfo = webUserInfoService.getById(uid);
            newWebUser.setUserInfo(userInfo);

            //user:uid:18    user:uname:xiaoming
            //注意：这里没有加失效时间，这相当于把缓存当成数据库使用了

            String unameKey = String.format(RedisKeys.User_Uname,newWebUser.getUsername());
            redisTemplate.opsForValue().set(unameKey,newWebUser);
            String uidkey = String.format(RedisKeys.User_uid,uid);
            redisTemplate.opsForValue().set(uidkey,newWebUser);
        }).start();



    }
}
